/*
 * Copyright 2003-2007 (c) Live Media Pty Ltd. <argot@einet.com.au> 
 *
 * This software is licensed under the Argot Public License 
 * which may be found in the file LICENSE distributed 
 * with this software.
 *
 * More information about this license can be found at
 * http://www.einet.com.au/License
 * 
 * The Developer of this software is Live Media Pty Ltd,
 * PO Box 4591, Melbourne 3001, Australia.  The license is subject 
 * to the law of Victoria, Australia, and subject to exclusive 
 * jurisdiction of the Victorian courts.
 */

package com.colony.networkvm;

import com.argot.DynamicTypeMap;
import com.argot.TypeException;
import com.argot.TypeLibrary;
import com.argot.TypeMapCore;
import com.argot.network.TypeServer;
import com.argot.remote.MetaLocation;
import com.argot.remote.MetaObject;
import com.colony.ColonyEnvironment;
import com.colony.ColonyException;
import com.colony.IColonyServer;
import com.colony.IContainer;
import com.colony.channel.ChannelServer;
import com.colony.channel.ChannelLoader;
import com.colony.remote.RemoteException;
import com.colony.remote.rpc.RpcDelegateFactory;
import com.colony.remote.rpc.RpcMetaServer;
import com.colony.remote.rpc.RpcMetaSkeleton;
import com.colony.transport.Server;

public class NvmServer
implements IColonyServer
{
	private boolean _isBound;
	
	private ColonyEnvironment _environment;
	private TypeLibrary _library;
	private IContainer _container;
	private NvmDelegateFactory _delegateFactory;
	private MetaLocation _hostLocation;
	private Server _link;
	private Server _channel;
	
	public NvmServer( MetaLocation hostLocation, Server link, Server channel )
	{
		_link = link;
		_channel = channel;
		_hostLocation = hostLocation;
		_delegateFactory = new NvmDelegateFactory();
	}
	
	public ColonyEnvironment getEnvironment()
	{
		return _environment;
	}

	public void bind( ColonyEnvironment environment ) 
	throws ColonyException, RemoteException, TypeException
	{
		if ( _isBound ) throw new RemoteException("Server already bound to environment");
		_isBound = true;

		_environment = environment;
		_container = environment.getHostContainer();
		_library = environment.getTypeLibrary();
		
		DynamicTypeMap dynMap = new DynamicTypeMap( _library );
		TypeMapCore.mapMeta( dynMap, _library );
		dynMap.map( 22, _library.getId("dictionary.map"));
		dynMap.map( 23, _library.getId("dictionary.words"));
		dynMap.map( 24, _library.getId("dictionary.definition"));
		dynMap.map( 25, _library.getId("dictionary.entry"));	
		dynMap.map( 26, _library.getId("meta.envelop"));
		dynMap.map( 27, _library.getId("meta.definition#envelop"));		
		
		NvmEnvironment nvmEnvironment = new NvmEnvironment(_environment, _delegateFactory, _library);
		NvmHostServer nvmHost = new NvmHostServer( nvmEnvironment, dynMap );
		_container.addObject( _hostLocation, INvmHost.TYPENAME, nvmHost );

		RpcDelegateFactory delegateFactory = new RpcDelegateFactory();
		delegateFactory.setBackDelegate( NvmHostServer.class, new RpcMetaSkeleton());
		RpcMetaServer rpcHost = new RpcMetaServer( delegateFactory, _container, dynMap);
		TypeServer typeServer = new TypeServer( _library, dynMap, rpcHost );			
		typeServer.setBaseObject( new MetaObject( _hostLocation, _library.getId(INvmHost.TYPENAME)));
		_link.setTypeLink(typeServer);

		if ( _channel != null )
		{
			ChannelServer channelServer = new ChannelServer( _library, _channel.getPool() );
			_channel.setTypeLink(channelServer.getBack());
			ChannelLoader.bindServerMap(dynMap, channelServer );
		}

	}

	public boolean isBound()
	{
		return _isBound;
	}
	
}
